package com.example.OnlineStorage.Controller.FileOperate;


import com.example.OnlineStorage.enums.GlobalVariables_String;
import com.example.OnlineStorage.pojo.Response.ApiResponse;
import com.example.OnlineStorage.service.FileOperate.FileOperateService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.enums.ParameterIn;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.Arrays;
import java.util.List;

@Tag(name = "用户文件操作API")
@RestController("FileOperate")
@RequestMapping("/FileOperate")
public class FileOperateController {

    private final FileOperateService FileOperateService;

    // 用户令牌的全局变量
    private final String TOKEN = GlobalVariables_String.TOKEN.getValue();

    public FileOperateController(FileOperateService FileOperateService) {
        this.FileOperateService = FileOperateService;
    }

    @Operation(summary = "获取用户的所有文件信息",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @GetMapping("/getFileDataJson")
    public ResponseEntity<Object> getFileDataJson(HttpServletRequest request){
     String UUID = request.getHeader(TOKEN);
     return ApiResponse.GetApiResponse()
             .ok()
             .body(FileOperateService.getFileDataJson(UUID))
             .build();
    }

    @Operation(summary = "创建文件夹",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "fromPath", description = "从哪个路径创建", required = true),
            @Parameter(name = "name", description = "文件夹名称", required = true),
    })
    @PostMapping("/createDirectory")
    public ResponseEntity<Object> createDirectory(String fromPath,
                                                  String name,
                                                  HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(FileOperateService.createDirectory(fromPath, name, UUID))
                .build();
    }

    @Operation(summary = "上传文件之前进行一次查询服务器是否有了该文件",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "fromPath", description = "从哪个路径上传", required = true),
            @Parameter(name = "name", description = "文件名称", required = true),
            @Parameter(name = "intactSHA256", description = "完整文件的SHA256值", required = true),
            @Parameter(name = "AllChunkSHA256", description = "所有文件块的SHA256值", required = true),
    })
    @PostMapping("/isExist")
    public ResponseEntity<Object> isExist(String fromPath,
                                          String name,
                                          String intactSHA256,
                                          String[] AllChunkSHA256,
                                          HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(FileOperateService.isExist(fromPath, name, intactSHA256, Arrays.asList(AllChunkSHA256), UUID))
                .build();
    }

    @Operation(summary = "上传文件分块",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "fromPath", description = "从哪个路径上传", required = true),
            @Parameter(name = "name", description = "文件名称", required = true),
            @Parameter(name = "intactSHA256", description = "完整文件的SHA256值", required = true),
            @Parameter(name = "ChunkSHA256", description = "文件块的SHA256值", required = true),
            @Parameter(name = "AllChunkSHA256", description = "所有文件块的SHA256值", required = true),
            @Parameter(name = "ChunkFile", description = "文件块", required = true),
    })
    @PostMapping("/putChunk")
    public ResponseEntity<Object> putChunk(String fromPath,
                                           String name,
                                           String intactSHA256,
                                           String ChunkSHA256,
                                           String[] AllChunkSHA256,
                                           MultipartFile ChunkFile,
                                           HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(FileOperateService.putChunk(fromPath, name, intactSHA256, ChunkSHA256, Arrays.asList(AllChunkSHA256), ChunkFile, UUID))
                .build();
    }

    @Operation(summary = "修改文件夹、文件的名称",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "fromPath", description = "要修改的路径", required = true),
            @Parameter(name = "newName", description = "新名称", required = true),
    })
    @PostMapping("/reviseName")
    public ResponseEntity<Object> reviseName(String fromPath,
                                             String newName,
                                             HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(FileOperateService.reviseName(fromPath, newName, UUID))
                .build();
    }

    @Operation(summary = "删除节点",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "fromPath", description = "要删除的路径", required = true),
    })
    @PostMapping("/deleteNode")
    public ResponseEntity<Object> deleteNode(String fromPath,
                                             HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(FileOperateService.deleteNode(fromPath, UUID))
                .build();
    }

    @Operation(summary = "删除多个文件节点",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "fromPath", description = "要删除的路径列表", required = true),
    })
    @PostMapping("/deleteNodes")
    public ResponseEntity<Object> deleteNodes(String[] fromPath,
                                              HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(FileOperateService.deleteNodes(fromPath, UUID))
                .build();
    }

    @Operation(summary = "恢复文件节点",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "fromPath", description = "恢复到哪个路径(只能是文件夹)", required = true),
            @Parameter(name = "cacheName", description = "缓存名称", required = true),
    })
    @PostMapping("/recoveryNode")
    public ResponseEntity<Object> recoveryNode(String fromPath,
                                               String cacheName,
                                               HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(FileOperateService.recoveryNode(fromPath, cacheName, UUID))
                .build();
    }

    @Operation(summary = "获取回收站文件节点列表",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @GetMapping("/getCacheName")
    public ResponseEntity<Object> getCacheName(HttpServletRequest request) {
        String UUID = request.getHeader(TOKEN);
        return ApiResponse.GetApiResponse()
                .ok()
                .body(FileOperateService.getCacheList(UUID))
                .build();
    }

    @Operation(summary = "移动节点",
            description = "**注意**：此API需要在请求头添加认证Token,字段名为 `Token`")
    @Parameters({
            @Parameter(name = "fromPath", description = "要移动的路径", required = true),
            @Parameter(name = "toPath", description = "要移动到的路径(只能是文件夹)", required = true),
    })
    @PostMapping("/moveNode")
    public ResponseEntity<Object> moveNode(String fromPath, String toPath, HttpServletRequest request) {
        String file = FileOperateService.moveNode(fromPath, toPath, request.getHeader(TOKEN));
        return ApiResponse.GetApiResponse().ok().body(file).build();
    }
}
